package cn.com.wxd.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.wxd.common.DateUtil;
import cn.com.wxd.common.GlobalConstant;
import cn.com.wxd.util.action.AccessLogUtil;
import cn.com.wxd.util.framework.LocalCacheUtil;
import cn.com.wxd.common.thread.ThreadPoolUtil;

/**
 * Title:
 * Description:
 * <p>
 * Company: Amumu管理平台
 * Copyright: Copyright (c) 2017
 * All right reserved.
 * Created by WangXuDong on 2017/6/9.
 *
 * @author WangXuDong
 * @version 1.0
 */
public class AccessLogFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(AccessLogFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //会话 cookie 中缺少HttpOnly属性
        response.setHeader("Set-Cookie", "name=" + DateUtil.getTimestamp() + "; Secure; HttpOnly");
        String urlStr = request.getRequestURI() + request.getQueryString();
        //防止脚本注入
        if (urlStr.contains("(")
                || urlStr.contains("javascript")
                || urlStr.contains("<")
                || urlStr.contains("%3C")
                || urlStr.contains(">")
                || urlStr.contains("%3E")
                || urlStr.contains(")")
                || urlStr.contains("eval")
                || urlStr.contains("VBScript")
                || urlStr.contains("WEB-INF")
                || urlStr.contains("web.xml")) {
            if (log.isWarnEnabled()) {
                log.warn("#####URL有非法脚本字符：防止脚本注入");
            }
            response.setStatus(403);
            return;
        }

        final HttpSession session = request.getSession();
        boolean is = session.getAttribute(request.getRemoteAddr()) == null
                || session.getAttribute(request.getRemoteAddr()).equals("");
        //如果是新创建的session
        if (session.isNew() && is) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    //添加一条访问记录，但是不会重复添加当天重复访问的人
                    int result = AccessLogUtil.addAccessLogtoTemp(request);
                    if (result == -1) {
                        log.error("查询或存入访问记录出现错误"
                                , new Exception("查询或存入访问记录出现错误,"
                                        + "Class:AccessLogUtil.addAccessLogtoTemp(request)"));
                    }
                }
            };
            try {
                ThreadPoolUtil.submintThread(runnable);
            } catch (Exception e) {
                log.error("用户访问记录没有被添加，线程池启动插入线程出现错误!", e);
            }
        }
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        LocalCacheUtil.getInstance().flush(GlobalConstant.ACCESSLOGCACHENAME);
    }
}
